/**
 * 
 */
package com.googlecode.lohr.parser.combinators.matcher;


import java.util.ArrayList;
import java.util.List;

import com.googlecode.lohr.parser.combinators.MatchResults;
import com.googlecode.lohr.parser.combinators.node.AbstractNode;
import com.googlecode.lohr.parser.combinators.node.ChoiceNode;

public class ChoiceMatcher extends Matcher
{
	protected final ArrayList<Matcher> matchers= new ArrayList<Matcher>();

	public ChoiceMatcher(Matcher[] matchers)
	{
		for (Matcher matcher:matchers)
			this.matchers.add(matcher);
	}
	public ChoiceMatcher()
	{
	}

	@Override
	public MatchResults match(MatchContext ctx, int start) 
	{
		final List<AbstractNode> combinedResults = new ArrayList<AbstractNode>();

		MatchResults err= null;
		for (int i = 0; i < matchers.size(); i++)
		{
			Matcher choice= matchers.get(i);
			MatchResults results= ctx.doMatch(choice, start);
			if (results.success())
			{
				for (final AbstractNode result : results.matches)
				{
					combinedResults.add(new ChoiceNode(this, result, i));
				}
			}
			else if (err == null || err.position < results.position)
				err= results;
		}

		if (combinedResults.isEmpty()) {
			if (err != null)
				return err;
			return new MatchResults("Expected "+getLabel(), start);
		}

		return new MatchResults(combinedResults);
	}

	public void addChoice(Matcher matcher) {
		this.matchers.add(matcher);
	}

	public void addChoices(Matcher... matchers) {
		for (Matcher matcher:matchers)
			this.matchers.add(matcher);
	}
}